﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using ibba.src.norisk.ServiceDeParaAreaSubLimite;
using System.Collections.Generic;
using ibba.src.sl.recursos.MVVM;
using System.Linq;

namespace ibba.src.norisk.ViewModels
{
    public class DeParaAreaSublimiteViewModel : ViewModelBaseCadastro<DeParaAreaSubLimite>, IEventsCadastro
    {
        #region IEventsCadastro Members

        public event EndInsert OnEndInsert;
        public event EndDelete OnEndDelete;

        #endregion

        private IServiceDeParaAreaSubLimite _serviceDeParaAreaSublimite;
        private List<DeParaAreaSubLimite> _todosDePara;

        public Boolean ProdutoUtilizaProcessamento = false;
        public Boolean EstrategiaUtilizaProcessamento = false;
        public Boolean AreaUtilizaProcessamento = false;

        public DeParaAreaSublimiteViewModel()
        {        
            base.TitleView = "DePara Área Sublimite";
            
            if (!base.IsInDesignMode)
            {
                base.Entidade = new DeParaAreaSubLimite();
                _todosDePara = new List<DeParaAreaSubLimite>();

                //base.Entidade.ValidarCampos.ErrorsChanged += new System.EventHandler<System.ComponentModel.DataErrorsChangedEventArgs>(ValidarCampos_ErrorsChanged);

                _serviceDeParaAreaSublimite = ServiceFactory.GetInstance().ServiceDeParaAreaSubLimite;

                ObterListaAreasSubLimite();
                ObterListaProdutosItau();
                ObterListaEstrategias();
                ObterListaAreasInstitucionais();

                DetalheProdutos = new DetailsAux<DeParaProdutoItau>();
                DetalheEstrategias = new DetailsAux<DeParaEstrategia>();
                DetalheAreasInstitucionais = new DetailsAux<DeParaAreaInstitucional>();

                DetalheProdutos.OnChangeTypeDetail +=new sl.recursos.DetailsAux<DeParaProdutoItau>.EventChangeTypeDetail(DetalheProdutos_OnChangeTypeDetail);
                DetalheEstrategias.OnChangeTypeDetail += new sl.recursos.DetailsAux<DeParaEstrategia>.EventChangeTypeDetail(DetalheEstrategias_OnChangeTypeDetail);
                DetalheAreasInstitucionais.OnChangeTypeDetail += new sl.recursos.DetailsAux<DeParaAreaInstitucional>.EventChangeTypeDetail(DetalheAreasInstitucionais_OnChangeTypeDetail);
            }        
        }

        
        //void ValidarCampos_ErrorsChanged(object sender, System.ComponentModel.DataErrorsChangedEventArgs e)
        //{
        //    RaisePropertyChanged("EnabledSaveButton");
        //}

        //public override bool EnabledSaveButton
        //{
        //    get
        //    {
        //        if ((Entidade.ValidarCampos.HasErrors == false) &&
        //            (StateView == Enums.StateView.Including || StateView == Enums.StateView.Editing))
        //            return true;
        //        else
        //            return false;
        //    }
        //}


        void DetalheProdutos_OnChangeTypeDetail(object sender, sl.recursos.eTypeDetail oldType, sl.recursos.eTypeDetail newType)
        {
            if (sender != null)
            {
                ((ServiceDeParaAreaSubLimite.DeParaProdutoItau)sender).TipoAcaoSQL = (ServiceDeParaAreaSubLimite.EnumseTipoAcaoSQL)newType;
                ((ServiceDeParaAreaSubLimite.DeParaProdutoItau)sender).RaisePropertyChangeImageStatus();
            }
        }

        void DetalheEstrategias_OnChangeTypeDetail(object sender, sl.recursos.eTypeDetail oldType, sl.recursos.eTypeDetail newType)
        {
            if (sender != null)
            {
                ((ServiceDeParaAreaSubLimite.DeParaEstrategia)sender).TipoAcaoSQL = (ServiceDeParaAreaSubLimite.EnumseTipoAcaoSQL)newType;
                ((ServiceDeParaAreaSubLimite.DeParaEstrategia)sender).RaisePropertyChangeImageStatus();
            }
        }

        void DetalheAreasInstitucionais_OnChangeTypeDetail(object sender, sl.recursos.eTypeDetail oldType, sl.recursos.eTypeDetail newType)
        {
            if (sender != null)
            {
                ((ServiceDeParaAreaSubLimite.DeParaAreaInstitucional)sender).TipoAcaoSQL = (ServiceDeParaAreaSubLimite.EnumseTipoAcaoSQL)newType;
                ((ServiceDeParaAreaSubLimite.DeParaAreaInstitucional)sender).RaisePropertyChangeImageStatus();
            }
        }

   
        public override void ObterPorId(int pId)
        {
            this.StartBusy();

            _serviceDeParaAreaSublimite.BeginObterDeParaAreaSubLimite(pId, (pAsyncResult) =>
                {
                    Deployment.Current.Dispatcher.BeginInvoke(()=>
                    {
                        try
                        {
                            var retorno = ((ServiceDeParaAreaSubLimite.IServiceDeParaAreaSubLimite)pAsyncResult.AsyncState).EndObterDeParaAreaSubLimite(pAsyncResult);

                            CarregarDados(retorno);

                        }
                        catch (Exception ex)
                        {
                            MessageBoxHelper.ShowErroMethod(base.TitleView, "ObterPorId", ex);
                        }
                        finally
                        {
                            this.EndBusy();
                        }
                    });
                }, _serviceDeParaAreaSublimite);
            
        }

        public void ObterTodos()
        {
            this.StartBusy();

            _serviceDeParaAreaSublimite.BeginObterTodos((pAsyncResult) =>
            {
                Deployment.Current.Dispatcher.BeginInvoke(() =>
                {
                    try
                    {
                        var retorno = ((ServiceDeParaAreaSubLimite.IServiceDeParaAreaSubLimite)pAsyncResult.AsyncState).EndObterTodos(pAsyncResult);

                        _todosDePara = retorno;
                    }
                    catch (Exception ex)
                    {
                        MessageBoxHelper.ShowErroMethod(base.TitleView, "ObterTodos", ex);
                    }
                    finally
                    {
                        this.EndBusy();
                    }
                });
            }, _serviceDeParaAreaSublimite);

        }

        private void CarregarDados(DeParaAreaSubLimite pDados)
        {
            base.Entidade = pDados;

            /*necessario para poder marcar o registro para exclusão*/
            pDados.ProdutosItau.ForEach(f => f.TipoAcaoSQL = EnumseTipoAcaoSQL.Update);
            pDados.Estrategias.ForEach(f => f.TipoAcaoSQL = EnumseTipoAcaoSQL.Update);
            pDados.AreasInstitucionais.ForEach(f => f.TipoAcaoSQL = EnumseTipoAcaoSQL.Update);

            DetalheProdutos.CarregarDetalhes(pDados.ProdutosItau , false);
            DetalheEstrategias.CarregarDetalhes(pDados.Estrategias, false);
            DetalheAreasInstitucionais.CarregarDetalhes(pDados.AreasInstitucionais, false);

            base.StateView = StateViewType.Viewing;

            ObterTodos();
        }

        public override void Excluir()
        {
            throw new System.NotImplementedException();
        }

        public override void Salvar()
        {

            base.StartBusy();

            Entidade.ProdutosItau = DetalheProdutos.ChangeSets;
            Entidade.Estrategias = DetalheEstrategias.ChangeSets;
            Entidade.AreasInstitucionais = DetalheAreasInstitucionais.ChangeSets;

            _serviceDeParaAreaSublimite.BeginSalvarDePara(Entidade,
                (pAsyncResult) =>
                {
                    Deployment.Current.Dispatcher.BeginInvoke(() =>
                    {
                        try
                        {
                            var retorno = ((ServiceDeParaAreaSubLimite.IServiceDeParaAreaSubLimite)pAsyncResult.AsyncState).EndSalvarDePara(pAsyncResult);

                            CarregarDados(retorno);                            
                        }
                        finally
                        {
                            this.EndBusy();
                        }
                    });
                }, _serviceDeParaAreaSublimite);
        }

        public override void Cancelar()
        {
            base.Cancelar();

            ProdutoItauSelecionado = null;
            EstrategiaSelecionado = null;
            AreaSubLimiteSelecionado = null;

            ObterPorId(Entidade.IdAreaSubLimite);
        }


        #region ObterListas

        #region [ Lista de Areas do Sublimite ]

        public bool EnabledSearchButton
        {
            get
            {
                if ((AreaSubLimiteSelecionado != null) &&
                    (base.StateView == StateViewType.None || StateView == StateViewType.Viewing))
                    return true;
                else
                    return false;
            }
        }

        private ServiceDeParaAreaSubLimite.AreaSubLimite _areaSubLimiteSelecionado;
        public ServiceDeParaAreaSubLimite.AreaSubLimite AreaSubLimiteSelecionado
        {
            get { return _areaSubLimiteSelecionado; }
            set 
            {
                if (base.SetValue("AreaSubLimiteSelecionado", ref _areaSubLimiteSelecionado, value))
                {
                    base.RaisePropertyChanged("EnabledSearchButton");
                }
            }
        }
        
        public List<ServiceDeParaAreaSubLimite.AreaSubLimite> ListaAreasSubLimite { get; private set; }

        private void ObterListaAreasSubLimite()
        {
            base.StartBusy();

            ListaAreasSubLimite = new List<ServiceDeParaAreaSubLimite.AreaSubLimite>();

            _serviceDeParaAreaSublimite.BeginObterAreasSublimite(
                (pAsyncResult) =>
                {
                    Deployment.Current.Dispatcher.BeginInvoke(() =>
                    {
                        try
                        {
                            var retorno = ((ServiceDeParaAreaSubLimite.IServiceDeParaAreaSubLimite)pAsyncResult.AsyncState).EndObterAreasSublimite(pAsyncResult);

                            ListaAreasSubLimite = retorno;
                        }
                        catch (Exception ex)
                        {
                            MessageBoxHelper.ShowErroMethod(base.TitleView, "ObterListaAreasSubLimite", ex);
                        }
                        finally
                        {
                            base.RaisePropertyChanged("ListaAreasSubLimite");
                            this.EndBusy();
                        }
                    });
                }, _serviceDeParaAreaSublimite);
        }

        #endregion

        #region [ Lista de Produtos Itau ]

        public bool EnabledAddProdutoItau
        {
            get
            {
                if ((ProdutoItauSelecionado != null && base.Entidade.Ativo) &&
                    (base.StateView == StateViewType.Changing || StateView == StateViewType.Inserting))
                    return true;
                else
                    return false;
            }
        }

        private ServiceDeParaAreaSubLimite.ProdutoItau _produtoItauSelecionado;
        public ServiceDeParaAreaSubLimite.ProdutoItau ProdutoItauSelecionado
        {
            get { return _produtoItauSelecionado; }
            set 
            {
                if (base.SetValue("ProdutoItauSelecionado", ref _produtoItauSelecionado, value))
                {
                    base.RaisePropertyChanged("EnabledAddProdutoItau");
                }                
            }
        }

        public List<ServiceDeParaAreaSubLimite.ProdutoItau> ListaProdutosItau { get; private set; }
        
        private void ObterListaProdutosItau()
        {
            base.StartBusy();

            ListaProdutosItau = new List<ServiceDeParaAreaSubLimite.ProdutoItau>();

            _serviceDeParaAreaSublimite.BeginObterProdutosItau(
                (pAsyncResult) =>
                {
                    Deployment.Current.Dispatcher.BeginInvoke(() =>
                    {
                        try
                        {
                            var retorno = ((ServiceDeParaAreaSubLimite.IServiceDeParaAreaSubLimite)pAsyncResult.AsyncState).EndObterProdutosItau(pAsyncResult);

                            ListaProdutosItau = retorno;
                        }
                        catch (Exception ex)
                        {
                            MessageBoxHelper.ShowErroMethod(base.TitleView, "ObterListaProdutosItau", ex);
                        }
                        finally
                        {
                            base.RaisePropertyChanged("ListaProdutosItau");
                            this.EndBusy();
                        }
                    });
                }, _serviceDeParaAreaSublimite);
        }

        #endregion

        #region [ Lista de Estrategia ]

        public bool EnabledAddEstrategia
        {
            get
            {
                if ((EstrategiaSelecionado != null && base.Entidade.Ativo) &&
                    (base.StateView == StateViewType.Changing || StateView == StateViewType.Inserting))
                    return true;
                else
                    return false;
            }
        }

        private ServiceDeParaAreaSubLimite.Estrategia _estrategiaSelecionado;
        public ServiceDeParaAreaSubLimite.Estrategia EstrategiaSelecionado
        {
            get { return _estrategiaSelecionado; }
            set
            {
                if (base.SetValue("EstrategiaSelecionado", ref _estrategiaSelecionado, value))
                    base.RaisePropertyChanged("EnabledAddEstrategia");
            }
        }

        public List<ServiceDeParaAreaSubLimite.Estrategia> ListaEstrategias { get; private set; }

        private void ObterListaEstrategias()
        {
            base.StartBusy();

            ListaEstrategias = new List<ServiceDeParaAreaSubLimite.Estrategia>();

            _serviceDeParaAreaSublimite.BeginObterEstrategias(
                (pAsyncResult) =>
                {
                    Deployment.Current.Dispatcher.BeginInvoke(() =>
                    {
                        try
                        {
                            var retorno = ((ServiceDeParaAreaSubLimite.IServiceDeParaAreaSubLimite)pAsyncResult.AsyncState).EndObterEstrategias(pAsyncResult);

                            ListaEstrategias = retorno;
                        }
                        catch (Exception ex)
                        {
                            MessageBoxHelper.ShowErroMethod(base.TitleView, "ObterListaEstrategias", ex);
                        }
                        finally
                        {
                            base.RaisePropertyChanged("ListaEstrategias");
                            this.EndBusy();
                        }
                    });
                }, _serviceDeParaAreaSublimite);
        }

        #endregion

        #region [ Lista de Áreas Institucionais ]

        public bool EnabledAddAreaInstitucional
        {
            get
            {
                if ((AreaInstitucionalSelecionado != null && base.Entidade.Ativo) &&
                    (base.StateView == StateViewType.Changing || StateView == StateViewType.Inserting))
                    return true;
                else
                    return false;
            }
        }

        private ServiceDeParaAreaSubLimite.AreaInstitucional _areaInstitucionalSelecionado;
        public ServiceDeParaAreaSubLimite.AreaInstitucional AreaInstitucionalSelecionado
        {
            get { return _areaInstitucionalSelecionado; }
            set
            {
                if (base.SetValue("AreaInstitucionalSelecionado", ref _areaInstitucionalSelecionado, value))
                    base.RaisePropertyChanged("EnabledAddAreaInstitucional");
            }
        }

        public List<ServiceDeParaAreaSubLimite.AreaInstitucional> ListaAreasInstitucionais { get; private set; }

        private void ObterListaAreasInstitucionais()
        {
            base.StartBusy();

            ListaAreasInstitucionais = new List<ServiceDeParaAreaSubLimite.AreaInstitucional>();

            _serviceDeParaAreaSublimite.BeginObterAreasInstitucionais(
                (pAsyncResult) =>
                {
                    Deployment.Current.Dispatcher.BeginInvoke(() =>
                    {
                        try
                        {
                            var retorno = ((ServiceDeParaAreaSubLimite.IServiceDeParaAreaSubLimite)pAsyncResult.AsyncState).EndObterAreasInstitucionais(pAsyncResult);

                            ListaAreasInstitucionais = retorno;
                        }
                        catch (Exception ex)
                        {
                            MessageBoxHelper.ShowErroMethod(base.TitleView, "ObterListaAreasInstitucionais", ex);
                        }
                        finally
                        {
                            base.RaisePropertyChanged("ListaAreasInstitucionais");
                            this.EndBusy();
                        }
                    });
                }, _serviceDeParaAreaSublimite);
        }

        #endregion
        
        #endregion

        #region CargaGridDetalhes

        private DetailsAux<DeParaProdutoItau> _detalheProdutos;
        public DetailsAux<DeParaProdutoItau> DetalheProdutos
        {
            get { return _detalheProdutos; }
            set { base.SetValue("DetalheProdutos", ref _detalheProdutos, value); }
        }

        private DetailsAux<DeParaEstrategia> _detalheEstrategia;
        public DetailsAux<DeParaEstrategia> DetalheEstrategias
        {
            get { return _detalheEstrategia; }
            set { base.SetValue("DetalheEstrategia", ref _detalheEstrategia, value); }
        }

        private DetailsAux<DeParaAreaInstitucional> _detalheAreasInstitucionais;
        public DetailsAux<DeParaAreaInstitucional> DetalheAreasInstitucionais
        {
            get { return _detalheAreasInstitucionais; }
            set { base.SetValue("DetalheAreasInstitucionais", ref _detalheAreasInstitucionais, value); }
        }
        #endregion

        #region Commands

        //private DelegateCommand<int> _commandObterPorId;
        //public DelegateCommand<int> CommandObterPorId
        //{
        //    get
        //    {
        //        if (_commandObterPorId == null)
        //            _commandObterPorId = new DelegateCommand<int>(id => ObterPorId(id));

        //        return _commandObterPorId;
        //    }
        //}

        private DelegateCommand _commandObterPorId;
        public DelegateCommand CommandObterPorId
        {
            get
            {
                if (_commandObterPorId == null)
                    _commandObterPorId = new DelegateCommand(() => ObterPorId(AreaSubLimiteSelecionado.IdAreaSubLimite));

                return _commandObterPorId;
            }
        }

        private DelegateCommand _commandAddDetailProdutoItau;
        public DelegateCommand CommandAddDetailProdutoItau
        {
            get
            {
                if (_commandAddDetailProdutoItau == null)
                    _commandAddDetailProdutoItau = new DelegateCommand(() => AddDetailProdutoItau());
                //() => DetalheProdutos.AddDetail(new DeParaProdutoItau()
                //        {
                //            Codigo = ProdutoItauSelecionado.Codigo,
                //            Descricao = ProdutoItauSelecionado.Descricao
                //        }));

                return _commandAddDetailProdutoItau;
            }
        }
        private void AddDetailProdutoItau()
        {
            if (ProdutoItauSelecionado == null)
            {
                MessageBoxHelper.ShowWarning(AppHelper.NomeSistema, "É necessário selecionar um registro.");
            }
            else
            {
                DeParaProdutoItau exist = null;
                string areaSubLimite = "";

                exist = DetalheProdutos.ListOC.ToList().Where(w => w.Codigo == ProdutoItauSelecionado.Codigo).FirstOrDefault();

                if (exist == null)
                {
                    foreach (var item in _todosDePara)
                    {
                        exist = item.ProdutosItau.Where(w => w.Codigo == ProdutoItauSelecionado.Codigo).FirstOrDefault();
                        if (exist != null)
                        {
                            areaSubLimite = string.Format("{0} - {1}", item.DescAreaSubLimite, item.DescAreaLimite);
                            break;
                        }
                    }
                }
                else
                {
                    areaSubLimite = string.Format("{0} - {1}", base.Entidade.DescAreaSubLimite, base.Entidade.DescAreaLimite);
                }

                if (exist == null)
                {
                    DetalheProdutos.AddDetail(new DeParaProdutoItau()
                            {
                                Codigo = ProdutoItauSelecionado.Codigo,
                                Descricao = ProdutoItauSelecionado.Descricao,
                                UtilizaProcessamento = ProdutoUtilizaProcessamento
                            });

                    ProdutoItauSelecionado = null;
                }
                else
                    MessageBoxHelper.ShowExclamation(AppHelper.NomeSistema, string.Format("Produto já vinculado ao Tipo de Limite \n[{0}]", areaSubLimite));

            }
        }

        private DelegateCommand _commandAddDetailEstrategia;
        public DelegateCommand CommandAddDetailEstrategia
        {
            get
            {
                if (_commandAddDetailEstrategia == null)
                    _commandAddDetailEstrategia = new DelegateCommand(() => AddDetailEstrategia());

                return _commandAddDetailEstrategia;
            }
        }
        private void AddDetailEstrategia()
        {
            if (EstrategiaSelecionado == null)
            {
                MessageBoxHelper.ShowWarning(AppHelper.NomeSistema, "É necessário selecionar um registro.");
            }
            else
            {
                DeParaEstrategia exist = null;
                string areaSubLimite = "";

                exist = DetalheEstrategias.ListOC.ToList().Where(w => w.Codigo == EstrategiaSelecionado.Codigo).FirstOrDefault();

                if (exist == null)
                {
                    foreach (var item in _todosDePara)
                    {
                        exist = item.Estrategias.Where(w => w.Codigo == EstrategiaSelecionado.Codigo).FirstOrDefault();
                        if (exist != null)
                        {
                            areaSubLimite = string.Format("{0} - {1}", item.DescAreaSubLimite, item.DescAreaLimite);
                            break;
                        }
                    }
                }
                else
                {
                    areaSubLimite = string.Format("{0} - {1}", base.Entidade.DescAreaSubLimite, base.Entidade.DescAreaLimite);
                }

                if (exist == null)
                {
                    DetalheEstrategias.AddDetail(new DeParaEstrategia()
                    {
                        Codigo = EstrategiaSelecionado.Codigo,
                        Descricao = EstrategiaSelecionado.Descricao,
                        UtilizaProcessamento = EstrategiaUtilizaProcessamento
                    });

                    EstrategiaSelecionado = null;
                }
                else
                    MessageBoxHelper.ShowExclamation(AppHelper.NomeSistema, string.Format("Estrategia já vinculada ao Tipo de Limite \n[{0}]", areaSubLimite));

            }
        }

        private DelegateCommand _commandAddDetailAreaInstitucional;
        public DelegateCommand CommandAddDetailAreaInstitucional
        {
            get
            {
                if (_commandAddDetailAreaInstitucional == null)
                    _commandAddDetailAreaInstitucional = new DelegateCommand(() => AddDetailAreaInst());

                return _commandAddDetailAreaInstitucional;
            }
        }

        private void AddDetailAreaInst()
        {
            if (AreaInstitucionalSelecionado == null)
            {
                MessageBoxHelper.ShowWarning(AppHelper.NomeSistema, "É necessário selecionar um registro.");
            }
            else
            {
                DeParaAreaInstitucional exist = null;
                string areaSubLimite = "";

                exist = DetalheAreasInstitucionais.ListOC.ToList().Where(w => w.Codigo == AreaInstitucionalSelecionado.Codigo).FirstOrDefault();

                if (exist == null)
                {
                    foreach (var item in _todosDePara)
                    {
                        exist = item.AreasInstitucionais.Where(w => w.Codigo == AreaInstitucionalSelecionado.Codigo).FirstOrDefault();
                        if (exist != null)
                        {
                            areaSubLimite = string.Format("{0} - {1}", item.DescAreaSubLimite, item.DescAreaLimite);
                            break;
                        }
                    }
                }
                else
                {
                    areaSubLimite = string.Format("{0} - {1}", base.Entidade.DescAreaSubLimite, base.Entidade.DescAreaLimite);
                }

                if (exist == null)
                {
                    DetalheAreasInstitucionais.AddDetail(new DeParaAreaInstitucional()
                    {
                        Codigo = AreaInstitucionalSelecionado.Codigo,
                        Descricao = AreaInstitucionalSelecionado.Descricao,
                        UtilizaProcessamento = AreaUtilizaProcessamento
                    });

                    AreaInstitucionalSelecionado = null;
                }
                else
                    MessageBoxHelper.ShowExclamation(AppHelper.NomeSistema, string.Format("Área Institucional já vinculada ao Tipo de Limite \n[{0}]", areaSubLimite));

            }
        } 

        #endregion
    }
}
